﻿#region File Description
//-----------------------------------------------------------------------------
// LoadingScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

using System;
using ForgottenTalez.GameStateManager.ScreenMan;
using ForgottenTalez.Renderers;
using ForgottenTalez.Renderers.Interface;
using Microsoft.Xna.Framework;


namespace ForgottenTalez.GameStateManager.Screens.TransitionScreens
{
    class LoadingScreen : GameScreen
    {
        #region Event
        public delegate bool WaitUntilTrue();
        public event WaitUntilTrue WaitUntilTrueEvent;
        #endregion

        #region Fields

        bool loadingIsSlow;
        bool otherScreensAreGone;
        bool canTransition = false;

        GameScreen[] screensToLoad;

        #endregion

        #region Initialization


        /// <summary>
        /// The constructor is private: loading screens should
        /// be activated via the static Load method instead.
        /// </summary>
        private LoadingScreen(ScreenManager screenManager, bool loadingIsSlow, GameScreen[] screensToLoad, IScreenRenderer renderer): base(renderer)
        {
            this.loadingIsSlow = loadingIsSlow;
            this.screensToLoad = screensToLoad;
            TransitionOnTime = TimeSpan.FromSeconds(1);
        }

        /// <summary>
        /// Activate the loading screen while other screens load Can be used to hook up a method that has to return true before the screen will continue, 
        ///  USAGE:LoadingScreen.Load(parameters).WaitUntilTrueEvent += YourMethod;
        ///  (Kyk in ForgottonTalezGame se constructor)
        /// </summary>
        /// <param name="screenManager"></param>
        /// <param name="loadingIsSlow"></param>
        /// <param name="screensToLoad"></param>
        /// <returns></returns>
        public static LoadingScreen Load(ScreenManager screenManager, bool loadingIsSlow, IScreenRenderer renderer, params GameScreen[] screensToLoad)
        {
            // Tell all the current screens to transition off.
            foreach (GameScreen screen in screenManager.GetScreens())
                screen.ExitScreen();

            // Create and activate the loading screen.
            LoadingScreen loadingScreen = new LoadingScreen(screenManager,
                                                            loadingIsSlow,
                                                            screensToLoad, 
                                                            renderer);
            screenManager.AddScreen(loadingScreen);
            return loadingScreen;
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the loading screen.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            // If all the previous screens have finished transitioning
            // off, it is time to actually perform the load.

            if (WaitUntilTrueEvent != null)
            {
                if (WaitUntilTrueEvent())
                    canTransition = true;
            }
            else
            {
                canTransition = true;
            }

            if (otherScreensAreGone && canTransition)
            {

                foreach (GameScreen screen in screensToLoad)
                {
                    if (screen != null)
                    {
                        ScreenManager.AddScreen(screen);
                    }
                    ScreenManager.RemoveScreen(this);
                }

                // Once the load has finished, we use ResetElapsedTime to tell
                // the  game timing mechanism that we have just finished a very
                // long frame, and that it should not try to catch up.
                ScreenManager.Game.ResetElapsedTime();
            }
        
        }


        /// <summary>
        /// Draws the loading screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // If we are the only active screen, that means all the previous screens
            // must have finished transitioning off. We check for this in the Draw
            // method, rather than in Update, because it isn't enough just for the
            // screens to be gone: in order for the transition to look good we must
            // have actually drawn a frame without them before we perform the load.
            if ((ScreenState == ScreenState.Active) &&
                (ScreenManager.GetScreens().Length == 1))
            {
                otherScreensAreGone = true;
            }
            base.Draw(gameTime);
        }


        #endregion

    }
}
